package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pureut.storage.domain.Warehouse;
import com.pureut.storage.dto.ReservoirAreaDto;
import com.pureut.storage.dto.WareLocationDto;
import com.pureut.storage.dto.WarehouseDto;
import com.pureut.storage.dto.WarehouseStringDto;
import com.pureut.storage.mapper.WarehouseMapper;
import com.pureut.storage.service.WarehouseService;
import com.pureut.storage.vo.WarehouseVo;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.domain.R;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.dict.utils.DictUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.system.api.RemoteStaffManagementService;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysStaffManagementDto;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/***
 * 仓库管理实现层
 * Author:C
 * Date:2022/12/13 17:26
 * @DESC
 */
@Service
@RequiredArgsConstructor
public class WarehouseServiceImpl implements WarehouseService {


    private final WarehouseMapper warehouseMapper;

    @DubboReference
    RemoteStaffManagementService remoteStaffManagementService;

    /**
     * 获取仓库列表
     *
     * @return
     */
    @Override
    public List<WarehouseDto> getList(WarehouseVo warehouseVo) {
        //获取仓库类型
        List<SysDictData> typeArray = DictUtils.getDictCache("warehouse_type");
        Map<String, String> typeMap = typeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取仓库列表
        List<WarehouseDto> warehouse = warehouseMapper.getWarehouse(warehouseVo);

        for (WarehouseDto ck : warehouse) {
            ck.setWarehouseTypeDict(typeMap.get(ck.getWarehouseType()));
            //库管人员
            if (ck.getResponsiblePerson() != null) {
                Long staffId = Long.valueOf(ck.getResponsiblePerson());
                R<SysStaffManagementDto> info = remoteStaffManagementService.getInfo(staffId);
                if (info.getData() != null) {
                    ck.setResponsiblePersonDict(info.getData().getStaffName());
                }
            }
            //库区列表
            List<ReservoirAreaDto> reservoirAreaDtoList = new ArrayList<>();
            //获取仓库下的库区
            List<Warehouse> warehouses = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, ck.getWarehouseCode()).eq(Warehouse::getWarehouseType, 2));
            for (Warehouse kq : warehouses) {
                if (ck.getWarehouseCode().equals(kq.getParentCode())) {
                    ReservoirAreaDto reservoirAreaDto = new ReservoirAreaDto();
                    BeanUtils.copyProperties(kq, reservoirAreaDto);
                    reservoirAreaDto.setVolume(String.valueOf(kq.getVolume()));
                    reservoirAreaDto.setCapacity(String.valueOf(kq.getCapacity()));
                    reservoirAreaDto.setWarehouseType(String.valueOf(kq.getWarehouseType()));
                    reservoirAreaDto.setWarehouseTypeDict(typeMap.get(String.valueOf(kq.getWarehouseType())));
                    reservoirAreaDto.setParentCode(ck.getParentCode());
                    reservoirAreaDtoList.add(reservoirAreaDto);
                }
                ck.setChildren(reservoirAreaDtoList);
                ck.setWarehouseTypeDict(typeMap.get(ck.getWarehouseType()));
            }
            //循环库区
            for (ReservoirAreaDto kqList : reservoirAreaDtoList) {
                //库位列表
                List<WareLocationDto> location = new ArrayList<>();
                //获取库区下的库位
                List<Warehouse> kw = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, kqList.getWarehouseCode()).eq(Warehouse::getWarehouseType, 3));
                for (Warehouse entity : kw) {
                    WareLocationDto wareLocationDto = new WareLocationDto();
                    BeanUtils.copyProperties(entity, wareLocationDto);
                    wareLocationDto.setVolume(String.valueOf(entity.getVolume()));
                    wareLocationDto.setCapacity(String.valueOf(entity.getCapacity()));
                    wareLocationDto.setWarehouseType(String.valueOf(entity.getWarehouseType()));
                    wareLocationDto.setWarehouseTypeDict(typeMap.get(String.valueOf(entity.getWarehouseType())));
                    wareLocationDto.setParentCode(kqList.getParentCode());
                    location.add(wareLocationDto);
                }
                kqList.setChildren(location);
            }
        }
        return warehouse;
    }

    /**
     * 新增仓库
     *
     * @param warehouseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addWarehouse(WarehouseVo warehouseVo) {
        Warehouse warehouse = new Warehouse();
        BeanUtils.copyProperties(warehouseVo, warehouse);
        warehouse.setDeptId(LoginHelper.getDeptId());
        warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
        warehouse.setCreateBy(LoginHelper.getUsername());
        warehouse.setCreateTime(new Date());
        warehouse.setParentCode(warehouseVo.getParentCode());
//        warehouse.setResponsiblePerson(warehouseVo.getResponsiblePerson());
        Warehouse one = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseVo.getWarehouseCode()));
        if (one == null) {
            return warehouseMapper.insert(warehouse) > 0;
        } else {
            throw new GlobalException("该编码已存在");
        }

    }

    /**
     * 修改仓库
     *
     * @param warehouseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateWarehouse(WarehouseVo warehouseVo) {
        Warehouse warehouse = warehouseMapper.selectById(warehouseVo.getId());
        if (warehouse.getWarehouseType() == 1) {
            warehouse.setResponsiblePerson(warehouseVo.getResponsiblePerson());
        }
        warehouse.setWarehouseName(warehouseVo.getWarehouseName());
        warehouse.setVolume(warehouseVo.getVolume());
        warehouse.setCapacity(warehouseVo.getCapacity());
//        warehouse.setBadArea(warehouseVo.getBadArea());
        warehouse.setRemark(warehouseVo.getRemark());
        //物料编码
        warehouse.setMaterialCode(warehouseVo.getMaterialCode());
        return warehouseMapper.updateById(warehouse) > 0;
    }

    /**
     * 查看
     *
     * @return
     */
    @Override
    public WarehouseDto getView(Long id) {
        //获取仓库类型
        List<SysDictData> typeArray = DictUtils.getDictCache("warehouse_type");
        Map<String, String> typeMap = typeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        WarehouseDto warehouseDto = new WarehouseDto();
        Warehouse warehouse = warehouseMapper.selectById(id);
        if (warehouse == null) {
            return null;
        }
//        if (warehouse.getResponsiblePerson() != 0) {
//            //库管人员
//            Long staffId = warehouse.getResponsiblePerson();
//            R<SysStaffManagementDto> info = remoteStaffManagementService.getInfo(staffId);
//            if (info.getData() != null) {
//                warehouseDto.setResponsiblePersonDict(info.getData().getStaffName());
//            }

            //获取用户名称
//            long userId = warehouse.getResponsiblePerson();
//            String userName = feignService.getUserName(userId);
//            warehouseDto.setUserName(userName);
//            warehouseDto.setResponsiblePerson(warehouse.getResponsiblePerson());
//        }
        BeanUtils.copyProperties(warehouse, warehouseDto);
        warehouseDto.setResponsiblePerson(String.valueOf(warehouse.getResponsiblePerson()));
        warehouseDto.setCapacity(String.valueOf(warehouse.getCapacity()));
        warehouseDto.setVolume(String.valueOf(warehouse.getVolume()));
        warehouseDto.setWarehouseType(String.valueOf(warehouse.getWarehouseType()));
        warehouseDto.setWarehouseTypeDict(typeMap.get(String.valueOf(warehouse.getWarehouseType())));
        warehouseDto.setMaterialCode(warehouse.getMaterialCode());
        return warehouseDto;
    }

    /**
     * 删除仓库
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteWarehouse(Long id) {
        //判断该仓库下是否有子区域信息
        Warehouse warehouse = warehouseMapper.selectById(id);
        List<Warehouse> warehouses = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, warehouse.getWarehouseCode()));
        if (warehouses.size() == 0) {
            return warehouseMapper.deleteById(warehouse) > 0;
        } else {
            throw new GlobalException("存在子区域，请先删除子区域");
        }
        //TODO 判断库位是否有绑定的物料信息
    }

    /**
     * 新增子区域
     *
     * @param warehouseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSubarea(WarehouseVo warehouseVo) {
        //如果是单体新增
        if ("1".equals(warehouseVo.getAddType())) {
            Warehouse byId = warehouseMapper.selectById(warehouseVo.getId());
            Warehouse warehouse = new Warehouse();
            BeanUtils.copyProperties(warehouseVo, warehouse);
            warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
            warehouse.setCreateBy(LoginHelper.getUsername());
            warehouse.setCreateTime(new Date());

            //物料编码
            warehouse.setMaterialCode(warehouseVo.getMaterialCode());
//            if (byId.getBadArea() == 1) {
//                warehouse.setBadArea(1);
//            } else {
//                warehouse.setBadArea(2);
//            }
            //验证编码是否唯一
            Warehouse one = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseVo.getWarehouseCode()));
            if (one == null) {
                return warehouseMapper.insert(warehouse) > 0;
            } else {
                throw new GlobalException("该编码已经存在");
            }
        } else {
            Warehouse byId = warehouseMapper.selectById(warehouseVo.getId());
            List<Warehouse> warehouses = new ArrayList<>();
            //多个新增
            for (int i = 0; i <= warehouseVo.getNumber() - 1; i++) {
                Warehouse warehouse = new Warehouse();
                if (i == 0) {
                    BeanUtils.copyProperties(warehouseVo, warehouse);
                    warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
                    warehouse.setWarehouseCode(warehouseVo.getCodePrefix() + warehouseVo.getStartCode());
                    warehouse.setWarehouseName(warehouseVo.getWarehouseName() + warehouseVo.getStartCode());
                    warehouse.setCreateBy(LoginHelper.getUsername());
                    warehouse.setCreateTime(new Date());

                    //物料编码
                    warehouse.setMaterialCode(warehouseVo.getMaterialCode());
//                    if (byId.getBadArea() == 1) {
//                        warehouse.setBadArea(1);
//                    } else {
//                        warehouse.setBadArea(2);
//                    }
                    //验证编码是否唯一
                    Warehouse one = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouse.getWarehouseCode()));
                    if (one == null) {
                        warehouses.add(warehouse);
                    } else {
                        throw new GlobalException("存在重复的编码");
                    }

                } else {
                    BeanUtils.copyProperties(warehouseVo, warehouse);
                    warehouse.setWarehouseType(Integer.parseInt(warehouseVo.getWarehouseType()));
                    warehouse.setWarehouseCode(addOne(warehouses.get(i - 1).getWarehouseCode()));
                    String s = addOne(warehouses.get(i - 1).getWarehouseCode());
                    String[] split = s.split("[^0-9]");
                    String numStr = split[split.length - 1];
                    warehouse.setWarehouseName(warehouseVo.getWarehouseName() + numStr);
                    warehouse.setCreateBy(LoginHelper.getUsername());
                    warehouse.setCreateTime(new Date());

                    //物料编码
                    warehouse.setMaterialCode(warehouseVo.getMaterialCode());
//                    if (byId.getBadArea() == 1) {
//                        warehouse.setBadArea(1);
//                    } else {
//                        warehouse.setBadArea(2);
//                    }
                    //验证编码是否唯一
                    Warehouse one = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouse.getWarehouseCode()));
                    if (one == null) {
                        warehouses.add(warehouse);
                    } else {
                        throw new GlobalException("存在重复的编码");
                    }

                }
            }
            return warehouseMapper.insertBatch(warehouses);
        }
    }

    /**
     * 根据库位编码获取仓库-库区-库位
     *
     * @param warehouseCode
     * @return
     */
    @Override
    public WarehouseStringDto getWarehouseCode(String warehouseCode) {
        WarehouseStringDto warehouseStringDto = new WarehouseStringDto();
        //库位
        Warehouse warehouseKw = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseCode));
        if (warehouseKw == null) {
            return warehouseStringDto;
        }
        //库区
        List<Warehouse> warehouseKq = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseKw.getParentCode()).eq(Warehouse::getWarehouseType, 2));
        //仓库
        List<Warehouse> warehouseCk = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseCode, warehouseKq.get(0).getParentCode()).eq(Warehouse::getWarehouseType, 1));
        warehouseStringDto.setCkId(warehouseCk.get(0).getId());
        warehouseStringDto.setKqId(warehouseKq.get(0).getId());
        warehouseStringDto.setKwId(warehouseKw.getId());
        warehouseStringDto.setCombinationName(warehouseCk.get(0).getWarehouseName() + "-" + warehouseKq.get(0).getWarehouseName() + "-" + warehouseKw.getWarehouseName());
        return warehouseStringDto;
    }

    /**
     * 获取仓库-库区-库位列表
     *
     * @return
     */
    @Override
    public List<String> getCombinationWarehouse() {
        //创建返回结果集
        List<String> result = new ArrayList<>();
        //获取仓库
        List<Warehouse> warehouseCk = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getWarehouseType, 1));

        for (Warehouse ck : warehouseCk) {
            //获取仓库下的库区
            List<Warehouse> warehouseKq = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, ck.getWarehouseCode()).eq(Warehouse::getWarehouseType, 2));
            //获取库区下的库位
            for (Warehouse kq : warehouseKq) {
                List<Warehouse> warehouseKw = warehouseMapper.selectList(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getParentCode, kq.getWarehouseCode()).eq(Warehouse::getWarehouseType, 3));
                for (Warehouse kw : warehouseKw) {
                    String combinationName = ck.getWarehouseName() + "-" + kq.getWarehouseName() + "-" + kw.getWarehouseName();
                    result.add(combinationName);
                }
            }
        }
        return result;
    }

    /**
     * 获取仓库
     *
     * @return
     */
    @Override
    public List<WarehouseDto> getCkById() {
        WarehouseVo warehouseVo = new WarehouseVo();
        List<WarehouseDto> warehouse = warehouseMapper.getWarehouse(warehouseVo);
        return warehouse;
    }

    /**
     * 根据仓库id获取仓库名称
     */
    @Override
    public String getWarehouseName(Long id) {
        Warehouse warehouse = warehouseMapper.selectById(id);
        return warehouse.getWarehouseName();
    }

    /**
     * 根据仓库id获取仓库-库区-库位数据
     */
    @Override
    public String getCombinationByWarehouseId(Long wareHouseId) {
        String result = "";
        //获取仓库
        Warehouse warehouseCK = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda()
            .eq(Warehouse::getId, wareHouseId)
            .eq(Warehouse::getWarehouseType, 1));
        //获取库区
        if (warehouseCK != null) {
            result = warehouseCK.getWarehouseName() + "-";
            Warehouse warehouseKQ = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda()
                .eq(Warehouse::getParentCode, warehouseCK.getWarehouseCode())
                .eq(Warehouse::getWarehouseType, 2));
            //获取库位
            if (warehouseKQ != null) {
                result = result + warehouseKQ.getWarehouseName() + "-";
                Warehouse warehouseKW = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda()
                    .eq(Warehouse::getParentCode, warehouseKQ.getWarehouseCode())
                    .eq(Warehouse::getWarehouseType, 3));
                if (warehouseKW != null) {
                    result = result + warehouseKW.getWarehouseName();
                }
            }
        }
        return result;
    }


    /**
     * 字符串末尾数字加1
     *
     * @param testStr
     * @return
     */
    public String addOne(String testStr) {
        //根据不是数字的字符拆分字符串
        String[] strs = testStr.split("[^0-9]");
        //取出最后一组数字
        String numStr = strs[strs.length - 1];
        //如果最后一组没有数字(也就是不以数字结尾)，抛NumberFormatException异常
        if (numStr != null && numStr.length() > 0) {
            //取出字符串的长度
            int n = numStr.length();
            //将该数字加一
            int num = Integer.parseInt(numStr) + 1;
            String added = String.valueOf(num);
            n = Math.min(n, added.length());
            //拼接字符串
            return testStr.subSequence(0, testStr.length() - n) + added;
        } else {
            throw new NumberFormatException();
        }
    }

}
